#pragma once
#include <iostream>
#include <vector>
#include <pthread.h>
#include<functional>
#include "LockGuard.hpp"
#include "InetAddr.hpp"
#include"threadpool.hpp"
#include"Log.hpp"
#include<string>
using task_t=std::function<void()>;
class Route
{
public:
    Route()
    {
        pthread_mutex_init(&_mutex, nullptr);
    }
    ~Route()
    {
        pthread_mutex_destroy(&_mutex);
    }
    void CheckAddr(InetAddr& who)
    {
        //LockGuard lockguard(&_mutex);
        for(auto& user:_online_user)
        {
            if(user==who)
            {
                 LOG(DEBUG, "%s is exists\n", who.AddrStr().c_str());
                 return;
            }
        }
         LOG(DEBUG, "%s is not exists, add it\n", who.AddrStr().c_str());
            _online_user.push_back(who);
    }
    void OffLine(InetAddr& who)
    {
        //LockGuard lockguard(&_mutex);
        auto iter=_online_user.begin();
        while(iter!=_online_user.end())
        {
            if(*iter==who)
            {
               LOG(DEBUG, "%s is offline\n", who.AddrStr().c_str());
                _online_user.erase(iter);
                break;
            }
            iter++;
        }
    }
    void ForwardHelper(int sockfd,const std::string& message,InetAddr& who)
    {
        //LockGuard lockguard(&_mutex);
        std::string send_message = "[" + who.AddrStr() + "]# " + message;
        for(auto& user:_online_user)
        {
            struct sockaddr_in peer = user.Addr();
            LOG(DEBUG, "Forward message to %s, message is %s\n", user.AddrStr().c_str(), send_message.c_str());
            sendto(sockfd,send_message.c_str(),send_message.size(),0,(struct sockaddr*)&peer,sizeof(peer));
        }
    }

    void Forward(int sockfd,const std::string message,InetAddr addr)
    {
        CheckAddr(addr);
        if(message=="QUIT"||message=="quit")
        {
            OffLine(addr);
        }
        // task_t func=std::bind(&Route::ForwardHelper,this,sockfd,message,addr);
        // ThreadPool<task_t>::GetInstance()->Enqueue(func);
        ForwardHelper(sockfd,message,addr);
        //std::cout<<"hello aaaaaaaaa"<<std::endl;
    }
private:
    std::vector<InetAddr> _online_user;
    pthread_mutex_t _mutex;
};
